package uploader;

import java.awt.HeadlessException;
import java.io.File;
import java.io.IOException;
import java.util.*;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
 * 主界面<br>
 * 使用Netbeans IDE画的主界面
 *
 * @author zhangqunshi@126.com
 * @version java1.8, 2013-7-16
 */
public class MainUI extends javax.swing.JFrame {

    private Map<String, String> fileMapping = new HashMap<>();

    /**
     * Creates new form
     */
    public MainUI() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        uploadButton = new javax.swing.JButton();
        closeButton = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        pathMappingTextArea = new javax.swing.JTextArea();
        jLabel2 = new javax.swing.JLabel();
        sourceFileTextField = new javax.swing.JTextField();
        browseButton = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        remotePathTextField = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        hostsTextArea = new javax.swing.JTextArea();
        jLabel4 = new javax.swing.JLabel();
        usernameTextField = new javax.swing.JTextField();
        passwordLabel = new javax.swing.JLabel();
        addButton = new javax.swing.JButton();
        pwdTextField = new javax.swing.JPasswordField();
        exportButton = new javax.swing.JButton();
        loadButton = new javax.swing.JButton();
        showCheckBox = new javax.swing.JCheckBox();
        resetButton = new javax.swing.JButton();
        clearButton = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
        filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
        filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("SCP Uploader v1.4");

        uploadButton.setMnemonic('r');
        uploadButton.setText("开始上传 (Alt+R)");
        uploadButton.setActionCommand("Upload");
        uploadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                uploadButtonActionPerformed(evt);
            }
        });

        closeButton.setText("关闭退出");
        closeButton.setActionCommand("Close");
        closeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeButtonActionPerformed(evt);
            }
        });

        jLabel1.setText("远程主机IP列表");

        pathMappingTextArea.setEditable(false);
        pathMappingTextArea.setColumns(20);
        pathMappingTextArea.setRows(5);
        jScrollPane2.setViewportView(pathMappingTextArea);

        jLabel2.setText("本地文件");

        sourceFileTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                sourceFileTextFieldKeyTyped(evt);
            }
        });

        browseButton.setText("浏览源文件");
        browseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseButtonActionPerformed(evt);
            }
        });

        jLabel3.setText("远程路径");

        remotePathTextField.setToolTipText("如果在unix环境，请使用反斜线。另外不带文件名，只是目录名");
        remotePathTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                remotePathTextFieldFocusLost(evt);
            }
        });

        hostsTextArea.setColumns(20);
        hostsTextArea.setRows(5);
        hostsTextArea.setToolTipText("每个IP地址独占一行");
        jScrollPane1.setViewportView(hostsTextArea);

        jLabel4.setText("用户名");

        passwordLabel.setText("密码");

        addButton.setMnemonic('a');
        addButton.setText("添加 (Alt+A)");
        addButton.setToolTipText("文件上传对应关系填到下表中");
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        exportButton.setText("导出当前方案");
        exportButton.setActionCommand("ExportSchema");
        exportButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportButtonActionPerformed(evt);
            }
        });

        loadButton.setText("导入方案");
        loadButton.setActionCommand("ImportSchema");
        loadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadButtonActionPerformed(evt);
            }
        });

        showCheckBox.setText("显示");
        showCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showCheckBoxActionPerformed(evt);
            }
        });

        resetButton.setText("全部清空");
        resetButton.setActionCommand("Reset");
        resetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                resetButtonActionPerformed(evt);
            }
        });

        clearButton.setText("清空");
        clearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearButtonActionPerformed(evt);
            }
        });

        jLabel5.setText("远程主机登陆信息");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(27, 27, 27)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(clearButton))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(exportButton)
                                .addGap(33, 33, 33)
                                .addComponent(loadButton)
                                .addGap(72, 72, 72)
                                .addComponent(uploadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(29, 29, 29)
                                .addComponent(resetButton))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 279, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(68, 68, 68)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel5)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addGroup(layout.createSequentialGroup()
                                            .addComponent(passwordLabel)
                                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                            .addComponent(pwdTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE))
                                        .addGroup(layout.createSequentialGroup()
                                            .addComponent(jLabel4)
                                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                            .addComponent(usernameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE))))))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(showCheckBox)
                            .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(sourceFileTextField)
                            .addComponent(remotePathTextField))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(filler2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(filler3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(7, 7, 7)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(browseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, Short.MAX_VALUE)))
                    .addComponent(jScrollPane2))
                .addGap(23, 23, 23))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(220, 220, 220))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(sourceFileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(browseButton)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(22, 22, 22)
                        .addComponent(filler2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel3)
                            .addComponent(remotePathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(addButton))
                        .addGap(8, 8, 8))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(filler3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)))
                .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(10, 10, 10)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 148, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(14, 14, 14)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(clearButton)
                    .addComponent(jLabel5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(uploadButton)
                            .addComponent(closeButton)
                            .addComponent(exportButton)
                            .addComponent(loadButton)
                            .addComponent(resetButton)))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel4)
                            .addComponent(usernameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(passwordLabel)
                            .addComponent(pwdTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(showCheckBox))))
                .addContainerGap(22, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void uploadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_uploadButtonActionPerformed
        // 上传文件按钮
        // TODO 还不支持一个文件上传到多个目录中

        if (fileMapping.isEmpty()) {
            JOptionPane.showMessageDialog(rootPane,
                    "You must select at least one file",
                    "Error",
                    JOptionPane.INFORMATION_MESSAGE);
            return;
        }

        // Get remote host ips
        String hostsText = hostsTextArea.getText();
        // TODO 可以提炼出一个公用方法
        List<String> hosts = new ArrayList<>();
        try {
            String[] lines = hostsText.split("\n");
            for (String line : lines) {
                System.out.println("=" + line);
                if (line.trim().equals("")) {
                    continue;
                }
                String ip = line.trim();
                if (ip.length() > 15) {
                    JOptionPane.showMessageDialog(rootPane,
                            "Host ip " + ip + " is not valid!",
                            "Error",
                            JOptionPane.INFORMATION_MESSAGE);
                }
                hosts.add(ip);
            }
            if (hosts.isEmpty()) {
                JOptionPane.showMessageDialog(rootPane,
                        "You must input at least one host ip",
                        "Error",
                        JOptionPane.INFORMATION_MESSAGE);
                return;
            }
        } catch (HeadlessException e) {
            System.err.println("Error read host ips: " + e.getMessage());
            JOptionPane.showMessageDialog(rootPane,
                    e.getMessage(),
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }

        // Get username and password
        String usr = usernameTextField.getText();
        String pwd = new String(pwdTextField.getPassword());

        if (usr.trim().equals("")) {
            JOptionPane.showMessageDialog(rootPane,
                    "Please enter the username",
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }

        // upload files to remote server
        for (int i = 0; i < hosts.size(); i++) {
            Iterator<String> it = fileMapping.keySet().iterator();
            while (it.hasNext()) {
                String localFile = it.next();
                String remotePath = fileMapping.get(localFile);
                String host = hosts.get(i);
                ScpClient scp = new ScpClient(host, usr, pwd);
                try {
                    // TODO 可以提供一次连接上传多个文件
                    scp.doUpload(localFile, remotePath);
                } catch (IOException e) {
                    String errMsg = "Fail to upload ["
                            + localFile + "] to ["
                            + host + "].\nError: "
                            + e.getMessage();
                    JOptionPane.showMessageDialog(rootPane,
                            errMsg,
                            "Error",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        }
        JOptionPane.showMessageDialog(rootPane,
                "Upload Finished!",
                "Success",
                JOptionPane.INFORMATION_MESSAGE);

    }//GEN-LAST:event_uploadButtonActionPerformed

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        // 添加要上传的文件映射

        String sourceFile = sourceFileTextField.getText();
        String remotePath = remotePathTextField.getText();

        if (sourceFile.trim().equals("")) {
            JOptionPane.showMessageDialog(rootPane,
                    "Please enter the source file!",
                    "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        if (remotePath.trim().equals("")) {
            JOptionPane.showMessageDialog(rootPane,
                    "Please enter the remote Path!",
                    "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        int lastSlash = remotePath.lastIndexOf("/");
        if (lastSlash > 0) {
            // TODO 还不支持上传过程中直接修改文件名
            String remoteFile = remotePath.substring(lastSlash);
            if (remoteFile.indexOf(".") > 0) {
                JOptionPane.showMessageDialog(rootPane,
                        "Remote Path must be a directory!",
                        "Error", JOptionPane.ERROR_MESSAGE);
                return;
            }
        }

        File srcFile = new File(sourceFile);
        if (!srcFile.exists()) {
            JOptionPane.showMessageDialog(rootPane,
                    "The source file doesn't exist!",
                    "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        if (fileMapping.containsKey(sourceFile)) {
            String oldRemoteFile = fileMapping.get(sourceFile);
            if (oldRemoteFile.equals(remotePath)) {
                JOptionPane.showMessageDialog(rootPane,
                        "The file has already exist in the following table !",
                        "Error", JOptionPane.ERROR_MESSAGE);
                sourceFileTextField.setText("");
                remotePathTextField.setText("");
                return;
            }
            // TODO if remote path is different, 
            // then ask the user if want to replace it.
        } else {
            fileMapping.put(sourceFile, remotePath);
        }

        String content = Utils.format(fileMapping);

        pathMappingTextArea.setText(content);
        sourceFileTextField.setText("");
        remotePathTextField.setText("");
    }//GEN-LAST:event_addButtonActionPerformed

    private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
        // 关闭窗口按钮
        dispose();
    }//GEN-LAST:event_closeButtonActionPerformed

    private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
        // 导出功能
        String hosts = hostsTextArea.getText();
        String user = usernameTextField.getText();
        char[] password = pwdTextField.getPassword();

        try {
            JFileChooser browse = new JFileChooser();
            int re = browse.showOpenDialog(rootPane);

            if (re == JFileChooser.APPROVE_OPTION) {
                File file = browse.getSelectedFile();
                file.createNewFile();
                Backup.exportConfig(file, fileMapping, hosts, user, password);

            } else {
                JOptionPane.showMessageDialog(rootPane,
                        "Please select a export file!");
                return;
            }

        } catch (IOException ex) {
            JOptionPane.showMessageDialog(rootPane,
                    "Error export: " + ex.getMessage(),
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
        JOptionPane.showMessageDialog(rootPane, "Export Successful!");

    }//GEN-LAST:event_exportButtonActionPerformed

    private void loadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadButtonActionPerformed
        // 导入功能
        try {
            JFileChooser browse = new JFileChooser();
            int re = browse.showOpenDialog(rootPane);
            File file;
            if (re == JFileChooser.APPROVE_OPTION) {
                file = browse.getSelectedFile();
            } else {
                JOptionPane.showMessageDialog(rootPane,
                        "Please select the backup file!");
                return;
            }
            Backup backup = new Backup();
            backup.importConfig(file);
            this.fileMapping = backup.getFilePathMapping();

            String content = Utils.format(fileMapping);

            pathMappingTextArea.setText(content);
            hostsTextArea.setText(backup.getHosts());
            usernameTextField.setText(backup.getUsername());
            pwdTextField.setText(backup.getPassword());

        } catch (IOException ex) {
            JOptionPane.showMessageDialog(rootPane,
                    "Error import backup file: " + ex.getMessage(),
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
        JOptionPane.showMessageDialog(rootPane, "Import Successful!");
    }//GEN-LAST:event_loadButtonActionPerformed

    private void showCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showCheckBoxActionPerformed
        // 是否显示密码
        if (showCheckBox.isSelected()) {
            pwdTextField.setEchoChar((char) 0);
        } else {
            pwdTextField.setEchoChar('*');
        }
    }//GEN-LAST:event_showCheckBoxActionPerformed

    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
        // 打开文件选择器,选择上传文件
        String prev = sourceFileTextField.getText();
        try {
            JFileChooser browse = null;
            if (prev != null && !"".equals(prev.trim())) {
                File prevFile = new File(prev);
                if (prevFile.exists()) {
                    String prevPath = prevFile.getAbsolutePath();
                    browse = new JFileChooser(prevPath);
                }
            }
            if (browse == null) {
                browse = new JFileChooser();
            }
            browse.setFileSelectionMode(JFileChooser.FILES_ONLY);
            int re = browse.showOpenDialog(rootPane);
            File f;
            if (re == JFileChooser.APPROVE_OPTION) {
                f = browse.getSelectedFile();
            } else {
                JOptionPane.showMessageDialog(rootPane,
                        "Please select a file!");
                return;
            }

            String p = f.getAbsolutePath();
            sourceFileTextField.setText(p);

        } catch (HeadlessException e) {
            JOptionPane.showMessageDialog(rootPane,
                    "Error: " + e.getMessage(),
                    "Error", JOptionPane.ERROR_MESSAGE);
        }
    }//GEN-LAST:event_browseButtonActionPerformed

    private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
        // 清空全部输入内容
        pathMappingTextArea.setText("");
        remotePathTextField.setText("");
        sourceFileTextField.setText("");
        hostsTextArea.setText("");
        fileMapping.clear();
    }//GEN-LAST:event_resetButtonActionPerformed

    private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
        // 清空上传文件列表输入框
        pathMappingTextArea.setText("");
        fileMapping.clear();
    }//GEN-LAST:event_clearButtonActionPerformed

    private void remotePathTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_remotePathTextFieldFocusLost
        String remotePath = remotePathTextField.getText();
        if (remotePath != null && !"".equals(remotePath.trim())) {
            remotePath = remotePath.replace("\\", "/");
            remotePathTextField.setText(remotePath);
        }
    }//GEN-LAST:event_remotePathTextFieldFocusLost

    private void sourceFileTextFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_sourceFileTextFieldKeyTyped
        // 输入本地上传文件路径
        String src = sourceFileTextField.getText();
        if (src != null && !"".equals(src)) {
            // 把windows分隔符替换成linux分隔符
            String remotePath = src.replace("\\", "/");

            // 复制本地文件所在目录名称到"远程路径"文本输入框
            int lastSlash = remotePath.lastIndexOf("/");
            if (lastSlash > 0) {
                remotePath = remotePath.substring(0, lastSlash);
            }
            remotePathTextField.setText(remotePath);
        }
    }//GEN-LAST:event_sourceFileTextFieldKeyTyped

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new MainUI().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JButton browseButton;
    private javax.swing.JButton clearButton;
    private javax.swing.JButton closeButton;
    private javax.swing.JButton exportButton;
    private javax.swing.Box.Filler filler1;
    private javax.swing.Box.Filler filler2;
    private javax.swing.Box.Filler filler3;
    private javax.swing.JTextArea hostsTextArea;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JButton loadButton;
    private javax.swing.JLabel passwordLabel;
    private javax.swing.JTextArea pathMappingTextArea;
    private javax.swing.JPasswordField pwdTextField;
    private javax.swing.JTextField remotePathTextField;
    private javax.swing.JButton resetButton;
    private javax.swing.JCheckBox showCheckBox;
    private javax.swing.JTextField sourceFileTextField;
    private javax.swing.JButton uploadButton;
    private javax.swing.JTextField usernameTextField;
    // End of variables declaration//GEN-END:variables
}
